<?php

namespace App\Models;

use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Cache;

/**
 * 空间预约表
 * Class StudyRoomReservationModel
 * @package app\common\model
 */
class StudyRoomReservation extends BaseModel
{
    use HasFactory;

    const CREATED_AT = 'create_time';
    const UPDATED_AT = 'change_time';

    public $table = 'study_room_reservation';



    /**
     * 关联配送申请
     */
    public function conApply()
    {
        return $this->hasMany(StudyRoomReservationApply::class, 'reservation_id', 'id');
    }


    /**
     * 关联文化配送排班信息
     */
    public function conSchedule()
    {
        return $this->hasMany(StudyRoomReservationSchedule::class, 'reservation_id', 'id');
    }

    /**
     * 用户预约报名填写信息
     */
    public static function getReservationApplyParam()
    {
        return [
            ['id' => 5, 'field' => 'img', 'value' => '头像'],
            ['id' => 1, 'field' => 'username', 'value' => '姓名'],
            ['id' => 2, 'field' => 'id_card', 'value' => '身份证'],
            ['id' => 8, 'field' => 'sex', 'value' => '性别'], //性别
            ['id' => 9, 'field' => 'age', 'value' => '年龄'], //年龄
            ['id' => 3, 'field' => 'tel', 'value' => '电话号码'],
            ['id' => 4, 'field' => 'reader_id', 'value' => '读者证'],
            ['id' => 7, 'field' => 'unit', 'value' => '单位名称'], //单位名称
            ['id' => 6, 'field' => 'remark', 'value' => '备注'], //备注  最多100字
            //  ['id' => 10, 'field' => 'accessory', 'value' => '附件'], //压缩包  最大3M
        ];
    }

    /**
     * 检查预约报名填报信息
     * @param array $act_info 活动信息
     * @param array $real_info
     * @param $data 需要验证的真实信息id用|连接起来    1、姓名   2 、身份证号码  3、电话号码   4、读者证号码    5、真实人物头像   6、备注  7 单位名称 8 性别 9 年龄  10、附件
     * @return array
     */
    public function checkApplyParam($res_info, array $real_info, array $data)
    {
        $where = [];
        foreach ($real_info as $key => $val) {
            if ($val == 1) {
                if (empty($data['username']) || mb_strlen($data['username']) < 2) {
                    throw new Exception('用户名规则不正确');
                } else {
                    $where['username'] = $data['username'];
                }
            } elseif ($val == 2) {
                if (empty($data['id_card']) || !is_legal_no($data['id_card'])) {
                    throw new Exception('身份证号码规则不正确');
                } else {
                    $where['id_card'] = $data['id_card'];
                }
            } elseif ($val == 3) {
                if (empty($data['tel']) || !verify_tel($data['tel'])) {
                    throw new Exception('电话号码规则不正确');
                } else {
                    $where['tel'] = $data['tel'];
                }
            } elseif ($val == 4) {
                if (empty($data['reader_id'])) {
                    throw new Exception('读者证不能为空');
                } else {
                    $where['reader_id'] = $data['reader_id'];
                }
            } elseif ($val == 5) {
                if (empty($data['img'])) {
                    throw new Exception('头像不能为空');
                } else {
                    $where['img'] = $data['img'];
                }
            } elseif ($val == 6) {
                // if (empty($data['remark'])) {
                //     throw new Exception('备注不能为空');
                // } else {
                $where['remark'] = addslashes($data['remark']); //备注可为空
                // }
            } elseif ($val == 7) {
                if (empty($data['unit'])) {
                    throw new Exception('单位不能为空');
                } else {
                    $where['unit'] = $data['unit'];
                }
            } elseif ($val == 8) {
                if (empty($data['sex']) || ($data['sex'] != 1 && $data['sex'] != 2)) {
                    throw new Exception('性别规则不正确');
                } else {
                    $where['sex'] = $data['sex'];
                }
            } elseif ($val == 9) {
                if (empty($data['age']) || !is_numeric($data['age']) || $data['age'] > 100) {
                    throw new Exception('年龄规则不正确');
                } else {
                    $where['age'] = $data['age'];
                }
            }
        }
        //判断年龄和性别是否符合要求
        if ($res_info['start_age'] || $res_info['end_age']) {
            $age = !empty($data['age']) ? $data['age'] : get_user_age_by_id_card($data['id_card']);

            if ($res_info['start_age'] && $res_info['start_age'] > $age) {
                throw new Exception('年龄不符合要求');
            }
            if ($res_info['end_age'] && $res_info['end_age'] < $age) {
                throw new Exception('年龄不符合要求');
            }
        }
        if ($res_info['astrict_sex'] && ($res_info['astrict_sex'] == 1 || $res_info['astrict_sex'] == 2)) {
            $sex = !empty($data['sex']) ? $data['sex'] : get_user_sex_by_id_card($data['id_card']);
            if ($res_info['astrict_sex'] != $sex) {
                throw new Exception('性别不符合要求');
            }
        }


        return $where;
    }

    /**
     * 处理预约参数
     * $data 管理员输入的活动信息
     */
    public function disRealInfo($data)
    {
        $is_real = $data['is_real'];
        $real_info = $data['real_info'];
        $real_info_arr = explode('|', $real_info);
        if ($data['astrict_sex'] && ($data['astrict_sex'] == 1 || $data['astrict_sex'] == 2)) {
            $is_real = 1;
            if (!in_array(2, $real_info_arr) && !in_array(8, $real_info_arr)) {
                $real_info .= "|8";
            }
        }
        if ($data['start_age'] || $data['end_age']) {
            $is_real = 1;
            if (!in_array(2, $real_info_arr) && !in_array(9, $real_info_arr)) {
                $real_info .= "|9";
            }
        }
        $real_info = trim($real_info, '|');
        return [$is_real, $real_info];
    }

    /**
     * 获取筛选列表
     * @param keywords string 搜索筛选
     * @param start_time string 开始时间
     * @param end_time string 结束时间
     */
    public function getFilterLists($keywords, $start_time, $end_time)
    {
        $res = $this->select(['id', 'cab_code', 'name'])
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('name', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($start_time, $end_time) {
                if ($start_time && $end_time) {
                    $query->whereBetween('create_time', [$start_time, $end_time]);
                }
            })
            ->where('is_del', 1)
            ->orderByDesc('id')
            ->get()
            ->toArray();
        return $res;
    }

    /**
     * 预约列表
     * @param limit int 分页大小
     * @param keywords string 搜索筛选
     * @param start_time string 开始时间
     * @param end_time string 结束时间
     * @param is_play string 是否发布 0 所有  是否发布  1.发布  2.未发布  默认2
     */
    public function lists($field = null, $keywords = null, $start_time = null, $end_time = null, $is_play = 0, $limit = 10)
    {
        if (empty($field)) {
            $field = [
                'id', 'img', 'cab_code', 'stack_number', 'name', 'astrict_sex', 'type_tag', 'number', 'apply_number', 'intro', 'province',
                'city', 'district', 'street', 'address', 'contacts', 'tel', 'is_play', 'is_real', 'real_info', 'qr_url', 'sign_way', 'create_time'
            ];
        }
        $res = $this->select($field)
            ->where(function ($query) use ($keywords) {
                if ($keywords) {
                    $query->where('name', 'like', "%$keywords%");
                }
            })->where(function ($query) use ($start_time, $end_time, $is_play) {
                if ($is_play) {
                    $query->where('is_play', $is_play);
                }
                if ($start_time && $end_time) {
                    $query->whereBetween('create_time', [$start_time, $end_time]);
                }
            })
            ->where('is_del', 1)
            ->orderByDesc('create_time')
            ->paginate($limit)
            ->toArray();
        foreach ($res['data'] as $key => $val) {
            $res['data'][$key]['type_tag'] = !empty($val['type_tag']) ? explode("|", $val['type_tag']) : [];
            $res['data'][$key]['intro'] = str_replace('&nbsp;', '', strip_tags($val['intro']));
        }
        return $res;
    }
    /**
     * 预约详情
     */
    public function detail($id, $field = null)
    {
        if (empty($field)) {
            $field = [
                'id', 'display_day', 'name', 'img', 'intro', 'type_tag', 'number', 'province', 'city', 'district', 'street', 'address',
                'apply_number', 'contacts', 'tel', 'start_age', 'end_age', 'is_reader', 'lon', 'lat', 'is_cancel', 'is_approval',
                'day_make_time', 'is_real', 'real_info', 'qr_url', 'sign_way'
            ];
        }
        $data = $this->select($field)->find($id);
        return $data;
    }


    /**
     * 判断某个活动是否有人报名
     */
    public function resIsMake($id)
    {
        $apply_status = StudyRoomReservationApply::where('reservation_id', $id)
            ->where(function ($query) {
                $query->whereIn("status", [1, 3, 6, 7]);
            })->first();
        return $apply_status ? true : false;
    }


    /**
     * 获取预约时间 和当前产品是否可以预约
     */
    public function getMakeTime($user_id = null, $reservation_info, $display_day = 7)
    {
        $week_time = get_continuous_week_time(true, $display_day); //获取未来一周的日期和星期几
        //获取所有的预约时间 可预约时间段
        $reservationApplyModel = new StudyRoomReservationApply();
        $reservationScheduleModel = new StudyRoomReservationSchedule();
        $reservationSpecialScheduleModel = new StudyRoomReservationSpecialSchedule();
        foreach ($week_time as $key => $val) {
            $make_list[$key]['date'] = date("Y/m/d", strtotime($val['date']));
            $make_list[$key]['week'] = $val['week'];

            $i = 0;
            $is_make = true; //true 表示已预约，不能预约
            $is_self_make = true; //true 表示自己已预约，不能预约
            $make_list[$key]['quantum'] = null;

            //先查看是有没特殊日期时间
            $special_info = $reservationSpecialScheduleModel->getSpecialListByDate($reservation_info['id'], $val['date']);
            if ($special_info) {
                $schedule_type = 2;
            } else {
                //查询是否有排版时间
                $schedule_info = $reservationScheduleModel->getScheduleList($reservation_info['id'], $val['weeks']);
                $schedule_type = 1;
            }
            if ($schedule_info) {
                $can_make_num = 0;
                $can_self_make_num = 0;
                foreach ($schedule_info as $k => $v) {
                    $temp_temp = $reservationApplyModel->getScheduleDetail($user_id, $reservation_info, $v, $val['date'], $schedule_type);
                    $make_list[$key]['quantum'][$i] = $temp_temp;
                    $i++;
                    if (!$temp_temp['is_make']) $can_make_num++;
                    if ($temp_temp['is_self_make']) $can_self_make_num++;
                }
                $is_make = $can_make_num > 0 ? false : true; //总的状态
                $is_self_make = $is_make && $can_self_make_num > 0 ? true : false; //总的状态
            }

            $make_list[$key]['is_make'] = $is_make; //总的状态
            $make_list[$key]['is_self_make'] = $is_self_make; //总的状态
        }
        return $make_list;
    }

    /**
     * 预约，查询逾期未签到用户，将状态改为已逾期，并且空出座位
     */
    public function checkApplyStatus()
    {
        //  $userInfoObj = new UserInfo();
        $reservationApply = new StudyRoomReservationApply();
        $res = $reservationApply->from($reservationApply->getTable() . ' as a')
            ->select('a.id', 'a.reservation_id', 'r.name', 'a.status', 'a.is_violate', 'a.user_id', 'a.account_id', 'a.score', 'a.expire_time')
            ->join('study_room_reservation as r', 'r.id', '=', 'a.reservation_id')
            ->where('expire_time', '<', date('Y-m-d H:i:s' , strtotime('-1 min')))
            ->where('r.is_sign', 1)
            ->whereIn('a.status', [1, 3])
            ->get();

        $controllerObj = new Controller();
        foreach ($res as $key => $val) {
            if ($val['is_violate'] == 1) {
                $val->is_violate = 2; //自动违规
                $val->violate_reason = '逾期未签到'; //自动违规
                $val->violate_time = $val->expire_time;

                $name = $this->where('id', $val['reservation_id'])->value('name');
                $system_id = $controllerObj->systemAdd('预约已违规', $val->user_id, $val->account_id, 52, $val->id, '您申请的预约：【' . $name . '】逾期未签到，自动违规', $val->expire_time);
                Cache::pull('violate_number'); //重置违规次数
                //  $userInfoObj->where('id', $val['user_id'])->increment('reservation_violate_num'); //增加违规次数
            }
            $val->status = 5; //并改为过期
            $val->save();

            /**退还积分 （过期未签到，暂时不返还积分，根据需求修改）*/
            // if (!empty($val['score'])) {
            //     $score_rule = new ScoreRuleController();
            //     $score_msg = $score_rule->getScoreMsg($val['score']);
            //     $score_rule->scoreReturn(5, $val['score'],$val['user_id'], $val['account_id'], '您申请的预约：【' . $val['name'] . '】未按时签到，' . $score_msg . ' ' . abs($val['score']) . ' 积分',$system_id);
            // }
        }
    }


    /**
     * 根据编号获取书房信息
     * @param 
     */
    public function getReservationInfoByCabCode($cab_code)
    {
        return  $this->where('cab_code', $cab_code)->where('is_del', 1)->first();
    }
}
